#include <iostream>

using std::cout;
using std::endl;


struct C {
    C() { cout << "Calling C()..." << endl; }
    C(const C &c) { 
        cout << "Calling C(const C&)..." << endl; 
    }
    C(C &&c) { 
        cout << "Calling C(C&&)" << endl; 
    }
    ~C() { cout << "Deconstructing C..." << endl; }
};

void f1(C& o) {
    cout << "Calling f1(C&)..." << endl;   
    C c(o);
}

template <typename T>
void f2(T&& o) {
    cout << "Calling f2(C&&)..." << endl;   
    T c(o);
}



int main(int argc, char *argv[]) {
    C objc;
    C &lc = objc;
    C &&rc = C();

    cout << "&lc: " << &lc << endl;
    cout <<  "&rc: " << &rc << endl;

    f1(lc); //lc: lvalue
    f1(rc); //rc: lvalue

    f2(lc); //lc: lvalue, T: C&, o: C&, c: C&(o)
    f2(rc); //rc: lvalue, T: C&, o: C&, c: C&(o)
    
    f2(objc); //objc: lvalue, T: C&, o: C&, c: C&(o)
    f2(C()); //C(): rvalue, T: C, o: C&&:lvalue, c: C(o):C(C&)   

    return 0;

}
